using Microsoft.EntityFrameworkCore;
using UwinEducation.Domain.IRepositories;
using UwinEducation.Infrastructure.Persistence;


namespace UwinEducation.Infrastructure.Repositories;

/// <summary>
/// 通用仓储实现
/// </summary>
public class Repository<TEntity, TKey> : IRepository<TEntity, TKey> where TEntity : class
{
    protected readonly ApplicationDbContext _context;
    protected readonly DbSet<TEntity> _dbSet;

    public Repository(ApplicationDbContext context)
    {
        _context = context;
        _dbSet = context.Set<TEntity>();
    }

    protected IQueryable<TEntity> BaseQuery()
    {
        var query = _dbSet.AsQueryable().AsNoTracking();
        if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity)))
        {
            query = query.Where(e => !((ISoftDelete)e).IsDeleted);
        }
        return query;
    }

    public virtual async Task<IEnumerable<TEntity>> GetAllAsync()
    {
        return await BaseQuery().ToListAsync();
    }

    public virtual async Task<TEntity> GetByIdAsync(TKey id)
    {
        return await BaseQuery().FirstOrDefaultAsync(e => EF.Property<TKey>(e, "Id").Equals(id));
    }

    public virtual async Task<TEntity> AddAsync(TEntity entity)
    {
        await _dbSet.AddAsync(entity);
        await _context.SaveChangesAsync();
        return entity;
    }

    public virtual async Task<List<TEntity>> AddRangeAsync(List<TEntity> entities)
    {
        await _dbSet.AddRangeAsync(entities);
        await _context.SaveChangesAsync();
        return entities;
    }
    public virtual async Task UpdateAsync(TEntity entity)
    {
        _dbSet.Update(entity);
        await _context.SaveChangesAsync();
    }
    public virtual async Task UpdateRangeAsync(List<TEntity> entities)
    {
        _dbSet.UpdateRange(entities);
        await _context.SaveChangesAsync();
    }

    public virtual async Task DeleteAsync(TKey id)
    {
        var entity = await GetByIdAsync(id);
        if (entity != null)
        {
            if (entity is ISoftDelete softDelete)
            {
                softDelete.IsDeleted = true;
                await UpdateAsync(entity);
            }
            else
            {
                _dbSet.Remove(entity);
                await _context.SaveChangesAsync();
            }
        }
    }

    public virtual IQueryable<TEntity> Query()
    {
        return BaseQuery();
    }
} 